<template>
  <div>
    <h2 ref="msg">msg: {{msg}}</h2>
    <h2 ref="msg2">msg2: {{msg2}}</h2>
    <button @click="test">测试</button>
  </div>
</template>

<script>
/* 
理解nextTick
  当我们同步更新完数据后, DOM并不会立即更新, DOM是异步更新的
  问题: 当更新完数据后, 不能立即得到更新后的DOM
  解决: 使用nextTick来指定回调函数, 在回调中操作更新后的DOM, 前提是nextTick必须在数据更新后立即调用
什么是Tick:
  就是一个任务队列中的事件回调
  一个事件回调是一个Tick
  在一个事件回调中去更新数据和调用nextTick, 
  更新DOM的异步回调与nextTick指定的回调会放在一个大的异步任务中处理的
内部结构
  内部有一个callbacks用来存储在一个事件回调中nexTick指定的回调和更新DOM的回调  (内部维护的异步任务队列)
  内部有一个queue用来存储在一个事件回调中用于更新DOM的render watcher, 那DOM更新的任务是一个整体的

  更新DOM的回调任务:
    遍历queue中的所有watcher, 去更新DOM
    第一次数据变化时, 就会将这个回调放入callbacks对象

  callbacks中保存哪些异步回调
    更新DOM回调(1个) + 我们调用nextTick的回调(n个)
  
  放入JS的异步队列中的回调
    遍历callbacks中所有回调函数, 并调用

  异步队列用哪种?
    先考虑微队列(Promise), 其次才考虑宏队列(setTimeout)

nextTick中用的是哪个异步技术呢?
  简单说: 优先使用微任务 => 宏任务
  详细说: promise => MutationObserver => setImmediate => setTimeout
*/
export default {
  name: 'NextTick',
  data () {
    return {
      msg: 'a',
      msg2: 'c'
    }
  },

  methods: {
    test () {
      this.msg2 += '++' // 更新一个其它数据

      // console.log(this.$refs.msg.innerHTML) // 旧的页面/dom
      this.$nextTick(() => { // 回调函数异步执行
        console.log(1, this.msg, this.$refs.msg.innerHTML)
      })

      this.msg += '--' // 更新数据后, DOM会异步更新

      this.$nextTick(() => { // 回调函数异步执行
        console.log(2, this.$refs.msg.innerHTML)
      })
    }
  },

  /* 
  queue:  保存更新DOM的多个watcher  数组队列
  定义一个更新DOM的函数: 遍历queue中的所有watcher, 去做DOM更新
  在数据第一次更新时, 就会调用nextTick将更新DOM的函数保存到callbacks中

  callbacks: 保存更新DOM的回调函数 和 我们调用$nextTick指定的所有回调函数
  定义一个函数(大的回调函数), 遍历callbacks中所有的函数进行调用

  大的回调函数会放入微队列或宏队列中进行异步执行

  */

  watch: {
    msg (value) { 
      
    }
  }
}
</script>

<style scoped>

</style>
